<?php

namespace App\Common\WX\Api;


use App\Common\Log;
use App\Common\WX\_Base;
use App\HttpController\x_app_system\setting\admin\setting;
use App\Model\t_s_accsuper_config;
use XWX\Common\H;
use XWX\Common\WebClient\WebClient;
use XWX\Common\WebClient\WebClientCo;

class ApiBase extends _Base
{
    static public function funcIns($entity = null, $use_coroutine = false)
    {
        if ($entity === null)
        {
            throw new \Exception('entity is null');
        }


        $config = null;
        if (is_a($entity, ApiConfig::class))
        {
            $config = $entity;
        }
        else if (is_a($entity, t_s_accsuper_config::class))
        {
            $config = new ApiConfig();
            $config->app_id = $entity->aconfig_app_id;
            $config->app_secret = $entity->aconfig_app_secret;
            $config->access_token = $entity->access_token();
        }
        else
        {
            throw new \Exception('entity type error');
        }


        $app = new static();
        $app->funcSet_entity($config);
        if ($use_coroutine === true)
        {
            $app->useCoroutine();
        }


        return $app;
    }


    protected $pub_use_coroutine = false;

    /**
     * 使用协程客户端请求
     *
     * @return $this
     */
    public function useCoroutine()
    {
        $this->pub_use_coroutine = true;

        return $this;
    }


    /**
     * @return ApiConfig
     */
    public function config()
    {
        return parent::funcGet_entity();
    }


    /**
     * 请求客户端
     * @return WebClient
     */
    public function getClient()
    {
        $client = null;
        if ($this->pub_use_coroutine)
        {
            $client = new WebClientCo();
        }
        else
        {
            $client = new WebClient();
        }

        return $client;
    }

    private $pub_base_api_root = 'https://api.weixin.qq.com/';


    /**
     * 获取微信请求URL
     *
     * @param $url_fix
     * @param null $access_token
     * @return string
     */
    public function funcGetApiUrl($url_fix, $access_token = null)
    {
        $url = "{$this->pub_base_api_root}{$url_fix}";
        if (H::funcStrHasAnyText($access_token))
        {
            $url = "{$url}?access_token={$access_token}";
        }

        return $url;
    }


    /**
     * 统一请求
     *
     * @param $url
     * @param string $method
     * @param null $data
     * @return \XWX\Common\XReturn
     * @throws \Exception
     */
    public function funcApi($url, $method = WebClient::METHOD_GET, $data = null)
    {
        Log::funcLog(__METHOD__);
        Log::funcLog(__METHOD__, $url);
        Log::funcLog(__METHOD__, $data);


        $client = $this->getClient();
        $client->setUrl($url);

        $res = null;
        if ($method == WebClient::METHOD_GET)
        {
            $res = $client->get();
        }
        else
        {
            if (!is_string($data))
            {
                $data = H::funcToStr($data);
            }

            $res = $client->post($data);
        }

        //请求返回错误
        if ($res->err())
        {
            return $res;
        }


        $r = $this->funcReturn($res->getBody());
        Log::funcLog(__METHOD__, $r);

        return $r;
    }


    /**
     * 统一返回
     *
     * @param $res
     * @return \XWX\Common\XReturn
     * @throws \Exception
     */
    public function funcReturn($res)
    {
        Log::funcLog(__METHOD__, $res);

        $json = json_decode($res, true);
        if ($json == false)
        {
            return $this->funcGetR(-654321, '格式有误');
        }

        $errcode = H::funcArrayGet($json, 'errcode');
        $errmsg = H::funcArrayGet($json, 'errmsg');
        if ($errcode != null || $errcode != 0)
        {
            return $this->funcGetR($errcode, $errmsg);
        }


        $r = $this->funcGetR($errcode, $errmsg);
        foreach ($json as $k => $v)
        {
            $r->setData($k, $v);
        }

        return $r;
    }
}